#include "KLogger.h"

#include "klogger/bbh_logger.h"

#include <string>
#include <iostream>
#include <stdarg.h>

static KLogger _global_logger;

class KLogger::KLoggerPrivate
{
public:
    bbh_logger_t * logger;

public:
    KLoggerPrivate() : logger(NULL)
    {}
    ~KLoggerPrivate()
    {
        uninit();
    }
    void init(const char*filepath, int rolling_interval, int rolling_size, int rolling_keep_num, const char*output_format)
    {
        int r;
        r = bbh_logger_create(filepath, &logger);
        bbh_logger_configure(logger, "rolling_interval", std::to_string(rolling_interval).c_str());
        bbh_logger_configure(logger, "rolling_size", std::to_string(rolling_size).c_str());
        bbh_logger_configure(logger, "rolling_keep_num", std::to_string(rolling_keep_num).c_str());
        bbh_logger_configure(logger, "pattern", output_format);
        bbh_logger_configure(logger, "level", "0");
        // 使配置生效
        bbh_logger_configure_enable(logger);
//        bbh_logger_set_output_format(logger, output_format);//"%d() %ms %us - %t(%T) xxx %+08.20c - [%v][%-010V] %%%m%n");
    }
    void uninit()
    {
        if (logger)
            bbh_logger_free(logger);
    }
};

void KLogger::initGlobal()
{
    //bbh_logger_init();
}
KLogger* KLogger::instance()
{
    return &_global_logger;
}

KLogger::KLogger() : private_ptr(new KLoggerPrivate())
{}

KLogger::~KLogger()
{
    delete private_ptr;
}

void KLogger::init(const char*filepath, int rolling_interval, int rolling_size, int rolling_keep_num, const char*output_format)
{
    private_ptr->init(filepath, rolling_interval, rolling_size, rolling_keep_num, output_format);
}

void  KLogger::write(int level, const char*s, size_t len)
{
    bbh_logger_write(private_ptr->logger, 0, 0, 0, 0, 0, level, s, len);
}
void  KLogger::print(int level, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, level, fmt, ap);
    va_end(ap);
}
void  KLogger::debug(const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, BBH_LOGGER_LEVEL_DEBUG, fmt, ap);
    va_end(ap);    
}
void  KLogger::info(const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, BBH_LOGGER_LEVEL_INFO, fmt, ap);
    va_end(ap);    
}
void  KLogger::notice(const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, BBH_LOGGER_LEVEL_NOTICE, fmt, ap);
    va_end(ap);    
}
void  KLogger::warn(const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, BBH_LOGGER_LEVEL_WARN, fmt, ap);
    va_end(ap);    
}
void  KLogger::error(const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, BBH_LOGGER_LEVEL_ERROR, fmt, ap);
    va_end(ap);    
}
void  KLogger::fatal(const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, 0, 0, 0, 0, 0, BBH_LOGGER_LEVEL_FATAL, fmt, ap);
    va_end(ap);    
}

void  KLogger::write(int level, const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*s, size_t len)
{
    bbh_logger_write(private_ptr->logger, filename, filename_len, function, function_len, line, level, s, len);
}
void  KLogger::print(int level, const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, level, fmt, ap);
    va_end(ap);
}
void  KLogger::debug(const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, BBH_LOGGER_LEVEL_DEBUG, fmt, ap);
    va_end(ap);    
}
void  KLogger::info(const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, BBH_LOGGER_LEVEL_INFO, fmt, ap);
    va_end(ap);    
}
void  KLogger::notice(const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, BBH_LOGGER_LEVEL_NOTICE, fmt, ap);
    va_end(ap);    
}
void  KLogger::warn(const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, BBH_LOGGER_LEVEL_WARN, fmt, ap);
    va_end(ap);    
}
void  KLogger::error(const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, BBH_LOGGER_LEVEL_ERROR, fmt, ap);
    va_end(ap);    
}
void  KLogger::fatal(const char*filename, size_t filename_len, 
                        const char*function, size_t function_len, int line, const char*fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    bbh_logger_vprint(private_ptr->logger, filename, filename_len, function, function_len, line, BBH_LOGGER_LEVEL_FATAL, fmt, ap);
    va_end(ap);    
}
